home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Resources
/
Chat & Communication
/
Digsby build 37
/
digsby_setup.exe
/
lib
/
mail
/
ymail.pyo
(
.txt
)
< prev
Wrap
Python Compiled Bytecode
|
2008-10-13
|
18KB
|
579 lines
# Source Generated with Decompyle++
# File: in.pyo (Python 2.5)
from __future__ import with_statement
import traceback
import cookielib
import urllib2
from threading import Lock
from datetime import datetime
from urlparse import urlparse
from urllib import quote
from logging import getLogger
from mail import Email, MailException
from util import UrlQuery, WebFormData, get_func_name, GetDefaultHandlers, threaded
from common.emailaccount import EmailAccount
log = getLogger('YahooMail')
class YahooMailException(MailException):
pass
class YahooMailAuthException(YahooMailException):
pass
class YahooMailBadDataException(YahooMailException):
pass
class YahooMailNoAccountException(YahooMailBadDataException):
pass
SessionIdReissue = 'Client.ClientRedirect.SessionIdReissue'
ExpiredCredentials = 'Client.ExpiredCredentials'
backup_server = 'us.mg1.mail.yahoo.com'
def ymail_action(func):
def ymail_action_wrapper(self, *a, **k):
if self._current_action is None:
self._current_action = func.func_name
try:
return func(self, *a, **k)
except YahooMailAuthException:
e = None
self.bad_pw()
except YahooMailNoAccountException:
e = None
self.no_mailbox()
except Exception:
e = None
traceback.print_exc()
finally:
self._current_action = None
return threaded(ymail_action_wrapper)
class YahooMail(EmailAccount):
protocol = 'ymail'
default_domain = 'yahoo.com'
def __init__(self, *args, **kwargs):
EmailAccount.__init__(self, *args, **kwargs)
self.init_jar()
self.update_lock = Lock()
self.updated_emails = None
self.updated_count = None
self.isBeta = True
self._current_action = None
def timestamp_is_time(self, tstamp):
return False
def get_email_address(self):
val = getattr(self, '_default_send_address', None)
if not val:
pass
return EmailAccount.get_email_address(self)
def init_jar(self):
try:
del self.u
except AttributeError:
pass
try:
del self._json_endpoint
except AttributeError:
pass
self.jar = cookielib.CookieJar()
self.http_opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.jar), *GetDefaultHandlers())
self.http_opener.addheaders = [
('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3')]
def get_json_endpoint(self):
try:
return self._json_endpoint
except AttributeError:
self._json_endpoint = UrlQuery('http://' + self.hostname + '/ws/mail/v1.1/jsonrpc', appid = 'YahooMailRC')
return self._json_endpoint
def set_json_endpoint(self, val):
self._json_endpoint = val
json_endpoint = property(get_json_endpoint, set_json_endpoint)
def _reset_state(self):
self.init_jar()
try:
del self.u
except AttributeError:
pass
try:
del self._json_endpoint
except AttributeError:
pass
def update(self):
log.error('ymail.update called from %s', get_func_name(2))
if self.offline_reason == self.Reasons.BAD_PASSWORD and hasattr(self, 'u'):
self.init_jar()
EmailAccount.update(self)
self.real_update(success = self.finish_update, error = self.warning)
def warning(self, e = None):
log.warning('yahoo blew up: %s', e)
log.error('ymail.warning called from %s', get_func_name(2))
if isinstance(e, YahooMailAuthException):
self.bad_pw()
else:
self.on_error(self._current_action)
return True
def bad_pw(self):
self.init_jar()
EmailAccount.bad_pw(self)
def finish_update(self, update):
if self.state == self.Statuses.OFFLINE:
log.error('finish_update exiting early, state is %r, reason is %r', self.state, self.offline_reason)
return None
if update is None:
log.warning('two updates were running at the same time')
return None
try:
(updated_emails, updated_count) = update
self.updated_emails = True
self._received_emails(updated_emails, updated_count)
except (TypeError, ValueError):
e = None
log.error('Invalid response from real_update: %r', update)
def real_update(self):
if self.update_lock.acquire(False):
try:
result = self.get_yMsgs()
if result:
return self._process_update_result(result)
else:
log.info('Got bad result from get_yMsgs: %r', result)
raise Exception('bad result')
finally:
self.update_lock.release()
real_update = threaded(real_update)
def _process_update_result(self, result):
(msgs, incount) = result
updated_count = incount
emails = []
for msg in msgs:
if msg.get('flags', { }).get('isRead', False):
continue
from_ = msg.get('from', { })
if not from_:
fromname = ''
else:
fromname = from_.get('name', from_.get('email', ''))
e = Email(id = msg['mid'], fromname = fromname, sendtime = datetime.fromtimestamp(msg['receivedDate']), subject = msg.get('subject', u''), attachments = [
True] * msg.get('flags', { }).get('hasAttachment', 0))
emails.append(e)
updated_emails = emails
log.info('reporting %d emails', incount)
return (updated_emails, updated_count)
def get_auth_form(self):
import ClientForm as ClientForm
try:
forms = ClientForm.ParseResponse(self.http_opener.open('https://mail.yahoo.com'), backwards_compat = False)
for f in forms:
if f.action == 'https://login.yahoo.com/config/login':
form = f
break
continue
else:
raise AssertionError('there should be a login form here')
except Exception:
e = None
traceback.print_exc()
form = ClientForm.HTMLForm('https://login.yahoo.com/config/login?', method = 'POST')
form.new_control('hidden', '.done', {
'value': 'http://mail.yahoo.com' })
form.new_control('text', 'login', {
'value': self.name.encode('utf-8') })
form.new_control('text', 'passwd', {
'value': self._decryptedpw().encode('utf-8') })
form.new_control('hidden', '.save', {
'value': 'Sign+In' })
form.new_control('hidden', '.done', {
'value': 'http://mail.yahoo.com' })
form['login'] = self.name.encode('utf-8')
form['passwd'] = self._decryptedpw().encode('utf-8')
return form
def authenticate(self):
log.info('authenticating')
form = self.get_auth_form()
try:
resp = self.http_opener.open(form.click())
except Exception:
e = None
raise YahooMailException('failed to load url: %r' % e)
respdata = resp.read()
resp.close()
respurl = resp.geturl()
if '/login' in respurl:
self.jar._cookies_lock.__enter__()
try:
self.jar._cookies['.yahoo.com']['/']['Y']
self.jar._cookies['.yahoo.com']['/']['T']
except KeyError:
self.jar._cookies_lock
self.jar._cookies_lock
log.warning('html was: %r', respdata)
raise YahooMailAuthException('failed to authenticate')
except:
self.jar._cookies_lock
finally:
pass
elif 'replica_agree?' in respurl:
pass
elif 'verify?' in respurl:
pass
else:
raise YahooMailAuthException('failed to authenticate, response url not expected', respurl)
try:
resp = self.http_opener.open('http://mail.yahoo.com/')
except Exception:
e = None
raise YahooMailException('failed to load url: %r' % e)
self.u = urlparse(resp.geturl())
resp.read()
resp.close()
try:
self.user_data = self.api('GetUserData')
self._default_send_address = self.user_data['result']['data']['userSendPref']['defaultFromAddress']
try:
self.isBeta = int(self.user_data['result']['data']['userFeaturePref'].get('optInState', '2')) == 2
except ValueError:
pass
except Exception:
traceback.print_exc()
log.info('Authenticated successfully')
def hostname(self):
if not hasattr(self, 'u'):
self.authenticate()
return self.u.hostname
hostname = property(hostname)
def get_yMsgs(self):
log.info('get_yMsgs')
try:
nummessages = _[1][0]['unread']
except YahooMailAuthException:
raise
except Exception:
nummessages = 25
nummessages = min(nummessages, 25)
result = self.api('ListMessages', fid = 'Inbox', numMid = 0, groupBy = 'unRead', startMid = 0, numInfo = nummessages, sortKey = 'date', sortOrder = 'down')
incount = result['result']['folder']['unread']
incount = int(incount)
return (result['result']['messageInfo'], incount)
def sort_emails(self, new = None):
pass
def open_url(self, url, data = None):
log.debug('open_url called from %s', get_func_name(2))
return self._open_url(url, data)
def _open_url(self, url, data = None):
datastring = None if not data else ' with data: ' + data
log.info('opening url: ' + url + datastring)
try:
response = self.http_opener.open(url, data)
except Exception:
e = None
ex = YahooMailException('failed to load url: %r' % e)
log.error('%r', ex)
raise ex
else:
log.info('httpopen succeeded')
respurl = urlparse(response.geturl())
if 'login.yahoo.com' in respurl.hostname:
log.info('login.yahoo.com in URL -- calling authenticate')
self.authenticate()
return self.open_url(url, data)
log.info('reading data from httpresponse')
strdata = response.read()
return (strdata, respurl)
finally:
if 'response' in locals():
log.debug('closing response')
response.close()
def delete(self, msg):
EmailAccount.delete(self, msg)
self.api('DeleteMessages', fid = 'Inbox', mid = [
msg.id])
delete = ymail_action(delete)
def markAsRead(self, msg):
EmailAccount.markAsRead(self, msg)
self.api('FlagMessages', fid = 'Inbox', mid = [
msg.id], setFlags = {
'read': 1 })
markAsRead = ymail_action(markAsRead)
def reportSpam(self, msg):
EmailAccount.reportSpam(self, msg)
mark = dict(FlagMessages = dict(fid = 'Inbox', mid = [
msg.id], setFlags = {
'spam': 1,
'read': 1 }))
move = dict(MoveMessages = dict(sourceFid = 'Inbox', destinationFid = '%40B%40Bulk', mid = [
msg.id]))
self.api('BatchExecute', call = [
mark,
move])
reportSpam = ymail_action(reportSpam)
def open(self, msg):
EmailAccount.open(self, msg)
mid = msg.id
if self.isBeta:
mid = quote(mid)
return UrlQuery('http://mrd.mail.yahoo.com/msg?', mid = mid, fid = 'Inbox')
def urlForEmail(self, msg):
try:
if self.web_login:
return str(self.make_login_string() + '&.done=' + quote(self.open(msg), safe = ''))
else:
return self.open(msg)
except Exception:
e = None
self.warning(e)
return self.open(msg)
def compose_link(self, to = '', subject = '', body = '', cc = '', bcc = ''):
extra = dict()
Body = body
subj = Subj = subject
To = to
Cc = cc
Bcc = bcc
for name in 'to To subj Subj subject body Body cc Cc bcc Bcc'.split():
if vars()[name]:
val = vars()[name]
if isinstance(val, unicode):
val = val.encode('utf-8')
extra[name.title()] = val
continue
return UrlQuery('http://compose.mail.yahoo.com/', **extra)
def compose(self, to = '', subject = '', body = '', cc = '', bcc = ''):
link = self.compose_link(to = to, subject = subject, body = body, cc = cc, bcc = bcc)
try:
if self.web_login:
return str(self.make_login_string() + '&.done=' + quote(link, safe = ''))
else:
return link
except Exception:
e = None
self.warning(e)
return link
def send_email(self, to = '', subject = '', body = '', cc = '', bcc = ''):
result = self.api('SendMessage', message = {
'subject': subject,
'from': {
'email': self.email_address },
'to': {
'email': to },
'simplebody': {
'text': body } })
if result['error'] is not None:
log.error('send_email(to=%r, subject=%r, body=%r) = %r', to, subject, body, result['error'])
raise YahooMailException(result['error']['message'])
return True
send_email = threaded(send_email)
def make_login_string(self):
self.jar._cookies_lock.__enter__()
try:
y = yBrowserCookie(self.jar._cookies['.yahoo.com']['/']['Y'])
t = yBrowserCookie(self.jar._cookies['.yahoo.com']['/']['T'])
finally:
pass
return 'http://msg.edit.yahoo.com/config/reset_cookies?&' + y + '&' + t + '&.ver=2'
def inbox_url(self):
try:
if self.web_login and hasattr(self, 'u'):
link = UrlQuery('http://mrd.mail.yahoo.com/inbox')
loginstr = self.make_login_string()
log.debug('returning login URL for yahoo inbox')
return str(loginstr + '&.done=' + quote(link, safe = ''))
else:
return 'http://mrd.mail.yahoo.com/inbox'
except Exception:
e = None
self.warning(e)
return 'http://mrd.mail.yahoo.com/inbox'
inbox_url = property(inbox_url)
def api(self, method, **params):
foo = None
loads = loads
dumps = dumps
import simplejson
recursed = params.pop('_recursed', 0)
recurse = False
try:
foo = self.http_opener.open(self.json_endpoint, dumps(dict(method = method, params = [
params]))).read()
log.debug_s('got data from yahoo: %r', foo)
if not foo.startswith('{'):
foo = foo.decode('z')
foo = loads(foo)
except YahooMailAuthException:
raise
except Exception:
e = None
if hasattr(e, 'read'):
foo = e.read()
log.debug('got error data from yahoo: %r', foo)
None if getattr(e, 'code', None) == 404 else None<EXCEPTION MATCH>YahooMailException
raise
finally:
if recurse and recursed < 5:
params['_recursed'] = recursed + 1
return self.api(method, **params)
return foo
class FakeYmail(YahooMail):
count = 1337
def __init__(self, username, password):
self.name = username
self.password = password
self.init_jar()
def _decryptedpw(self):
return self.password
def __len__(self):
return 1337
if __name__ == '__main__':
import main
main.setup_log_system()
f = FakeYmail('username', 'passwordShouldNotBeInSourceCode')
f.authenticate()
from pprint import pprint
msgs = [ m for m in f.get_yMsgs()[0] ]
print len(msgs)
pprint(msgs)
class yBrowserCookie(str):
def __new__(cls, cookie):
return str.__new__(cls, '.' + cookie.name.lower() + '=' + cookie.name + '=' + quote(cookie.value, safe = '/=') + ';+path=' + cookie.path + ';+domain=' + cookie.domain)